#include "network_layer/nw_definitions.h"


#ifndef QUEUE_H
#define QUEUE_H

struct pkt_node
{
	PACKET*			 	pkt;      
    struct pkt_node*	next;          //next buffer node pointer
};
	
	
struct queue
{
    struct pkt_node*	first;
    struct pkt_node*	last;
    unsigned int		length;
};

void q_setup(struct queue* q)
{
    q->first = q->last = NULL;
    q->length = 0;
}
 
bool q_is_empty (const struct queue *q)
{
    return q->first == NULL;
}

void q_insert(struct queue* q, PACKET* pkt)
{    
    struct pkt_node* node = (struct pkt_node*) malloc(sizeof(struct pkt_node));	//memory for a new pkt node

	/*
	 * filling the node
	 */
    node->pkt = pkt;
    node->next = NULL;
    
    if (q->first == NULL) {	//queue empty before
        q->first = q->last = node;
    } else {
        q->last->next = node;
        q->last = node;
    }
    q->length++;
}
 
PACKET* q_pull(struct queue *q)
{
	PACKET* pkt = NULL;
    if (!q->first) { //queue is empty
        return pkt;
    }
    
    pkt = q->first->pkt;
    
    struct pkt_node* to_clean = q->first;
    
    if (q->first == q->last) {	//queue with only 1 element
        q->first = q->last = NULL;
    } else { //queue with more then 1 element
        q->first = q->first->next;
	}
	q->length--;
    free(to_clean); //note: packet space will be cleaned after successfull transmission
    return pkt;
}

typedef struct queue* BUFFER;

#endif
